﻿// <copyright file="StatsPanel.xaml.cs" company="NorthCoast NERO">
//     NorthCoast NERO. All rights reserved.
// </copyright>
// <author>Eric Kociecki</author>
namespace NcnPlayerCheckIn.Controls
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    /// <summary>
    /// Interaction logic for StatsModePanel.xaml
    /// </summary>
    public partial class StatsPanel : UserControl, INotifyPropertyChanged
    {
        /// <summary>
        /// Initializes a new instance of the StatsPanel class.
        /// </summary>
        public StatsPanel()
        {
            this.InitializeComponent();

            this.DataContext = this;
        }

        /// <summary>
        /// This event indicates that a property has changed.  It is used for data binding to UI elements.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Gets or sets the object reference to the parent window.  This allows access to class members that are shared between all of the custom panels.
        /// </summary>
        public MainWindow ParentWindow { get; set; }

        /// <summary>
        /// Gets a count of all the players.  This includes players who have checked out.
        /// </summary>
        public int TotalPlayers
        {
            get { return this.PlayerList.Count; }
        }

        /// <summary>
        /// Gets the sum of all players' build totals
        /// </summary>
        public int TotalBuild
        {
            get { return this.PlayerList.Sum(Player => Player.BuildTotal); }
        }

        /// <summary>
        /// Gets the sum of PC game days.
        /// </summary>
        public int TotalPcGameDays
        {
            get { return this.PlayerList.Sum(Player => Player.PcDaysCount); }
        }

        /// <summary>
        /// Gets the number of players who are PCing for at least one game day.
        /// </summary>
        public int TotalPcs
        {
            get
            {
                int count = 0;
                foreach (Player player in this.PlayerList)
                {
                    if (player.PcDaysCount > 0)
                    {
                        count++;
                    }
                }

                return count;
            }
        }

        /// <summary>
        /// Gets the number of players who are NPCing for at least one game day.
        /// </summary>
        public int TotalNpcs
        {
            get
            {
                int count = 0;
                foreach (Player player in this.PlayerList)
                {
                    if (player.NpcDaysCount > 0)
                    {
                        count++;
                    }
                }

                return count;
            }
        }

        /// <summary>
        /// Gets the average player level of all players who are PCing for at least one game day.
        /// </summary>
        public int APL
        {
            get
            {
                decimal totalLevels = 0;
                foreach (Player player in this.PlayerList)
                {
                    if (player.PcDaysCount > 0)
                    {
                        totalLevels += player.CharacterLevel;
                    }
                }

                return (int)Math.Round(totalLevels / this.TotalPcs);
            }
        }

        /// <summary>
        /// Gets the number of players who are new to NERO.
        /// </summary>
        public int TotalNewPlayers
        {
            get
            {
                int newPlayersCount = 0;
                foreach (Player player in this.PlayerList)
                {
                    foreach (DiscountType dt in player.Discounts)
                    {
                        if (dt == DiscountTypes.NewPlayer)
                        {
                            newPlayersCount++;
                        }
                    }
                }

                return newPlayersCount;
            }
        }

        /// <summary>
        /// Gets the number of players who have not paid for any reason.  This includes new players, owners, game day credits, etc.
        /// </summary>
        public int TotalNonPays
        {
            get
            {
                int count = 0;
                foreach (Player player in this.PlayerList)
                {
                    if (player.EventFee == 0)
                    {
                        count++;
                    }
                }

                return count;
            }
        }

        /// <summary>
        /// Gets a list of all Players that have checked in at this event (some may have also checked out, but they are still tracked here).  This is a pass through to the MainWindow.PlayerList object.
        /// </summary>
        private Collection<Player> PlayerList
        {
            get { return this.ParentWindow.PlayerList; }
        }

        /// <summary>
        /// Forces an update of the stats that are displayed in the UI for this panel.
        /// </summary>
        public void UpdateStats()
        {
            foreach (FrameworkElement fe in this.mainPanel.Children)
            {
                TextBox tb = fe as TextBox;

                if (tb != null)
                {
                    tb.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
                }
            }
        }

        /// <summary>
        /// Fires the correct PropertyChanged event based on the given property name.
        /// </summary>
        /// <param name="info">The name of the property that has changed.</param>
        protected void NotifyPropertyChanged(string info)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }
}
